package com.lanhai.zhonglai.impl;


import java.util.Arrays;
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.lanhai.zhonglai.MsgCore;
import com.lanhai.zhonglai.beans.AgvBean;
import com.lanhai.zhonglai.beans.AgvDataBean;
import com.lanhai.zhonglai.beans.AgvMountBean;
import com.lanhai.zhonglai.beans.StationBean;
import com.lanhai.zhonglai.beans.DotBean;
import com.lanhai.zhonglai.dao.StationGroupDao; 
import com.lanhai.zhonglai.dao.RoadDao;
import com.lanhai.zhonglai.dispatch.AgvCmdMap;
import com.lanhai.zhonglai.dispatch.QrLeaveCheck;
import com.lanhai.zhonglai.dispatch.StationCmdMap;
import com.lanhai.zhonglai.enums.AgvCurrentTransEnum;
import com.lanhai.zhonglai.enums.AgvMountTypeEnum;
import com.lanhai.zhonglai.enums.CacheStationEnumType;
import com.lanhai.zhonglai.enums.TransDirectionEnum;
import com.lanhai.zhonglai.interfaces.IAgv;
import com.lanhai.zhonglai.interfaces.IAgvEvent;
import com.lanhai.zhonglai.interfaces.IAgvMount;
import com.lanhai.zhonglai.interfaces.ICmdLog;
import com.lanhai.zhonglai.interfaces.IStation; 
import com.lanhai.zhonglai.interfaces.IDot;
import com.lanhai.zhonglai.interfaces.IDotEvent;
import com.lanhai.zhonglai.interfaces.IPower;
import com.lanhai.zhonglai.interfaces.IRoad; 

@Service
public class DotEventImpl implements IDotEvent {
	@Autowired
	IAgv iAgv;

	@Autowired
	IAgvMount iAgvMount;

	@Autowired
	IStation iStation;

	@Autowired
	IDot iDot;

	@Autowired
	IAgvEvent iAgvEvent;

	@Autowired
	IPower iPower;

	@Autowired
	IRoad iRoad;

	@Autowired
	ICmdLog iCmdLog;
 

	@Autowired
	AgvCmdMap agvCmdMap;
	
	@Autowired
	QrLeaveCheck qrCheck;

 
 
	 
	/**
	 * 只处理一次
	 */
	@Override
	public void arrivedDecide(AgvBean agv, DotBean dot, AgvDataBean data) {
		// 异常装料状态
		if (data.getMountType() == AgvMountTypeEnum.Error) {
			// 错误的装卸状态，不处理
			MsgCore.sendMsg(agv.getAgvId(), "花篮数量异常，暂停");
			return;
		}

		// 决策点选择 
		switch(dot.getDotno()) {
		case 350:
			//制绒上料判断
			d350(agv,data,dot  );
			break;
		case 363:
			//只处理发料小车，充电或者去201
			p363(agv  );
			break;
		case 366:
			//制绒下料
			d366(agv,data,dot );
			break;
		case 368:
			//判断POPAID上料
			d368(agv,data,dot );
			break; 
		case 390:
			//空车去BOE下料或者451，有料去BOE上料
			d390(agv,data,dot );
			break;
		case 392:
			d392(agv,data,dot );
			break;
		case 397:
			d397(agv,data,dot );
			break;
		case 406:
			//扩散上料判断点
			d406(agv,data,dot );
			break;
		case 403:
			d403(agv,data,dot );
			break;
		case 425:
			//判断BSG，或者空车充电
			d425(agv,data,dot );
			break;
		case 437:
			//判断碱抛下料或者去366
			d437(agv,data,dot );
			break;
		case 451:
			//空车去393，否则去ALD湿法
			d451(agv,data,dot );
			break;
		case 475:
			//判断镀膜(正膜）
			d475(agv,data,dot );
			break;
		case 477:
			d477(agv,data,dot);
			break;
		case 478:
			//扩散上料机台选择
			d478(agv,data,dot );
			break;
		case 479:
			//退火上料选择
			d479(agv,data,dot );
			break;
		case 476:
			//丝网
			d476(agv,data,dot );
			break;
		case 518:
			d518(agv,data,dot );
		case 729:
			d729(agv,data,dot );
			break;
		}
		 
	}

	/**
	 * 充电桩
	 */
	@Override
	public void arrivedPower(AgvBean agv, DotBean dot ) {
		//
	}

	/**
	 * 路由点 AGV自带路由优先
	 */
	@Override
	public void arrivedRoute(AgvBean agv, DotBean dot) {
		if(dot.getDotno()==362) {
			int target=364;
			if(agv.getAgvId()==19||agv.getAgvId()==20) {
				//发料小车
				target=363;
			}else {
				//大车
				target=364;
			}
			int road=iRoad.getNormalRoad(362, target);
			if(road>0) {
				iAgvEvent.toRoad(agv, road);
			}else {
				MsgCore.sendMsg(agv.getAgvId(), String.format("缺少%d到%d的路线",362, target));
			}
		}else { 
			if(agv.getNextRoad()>0) { 
				int p=agv.getNextRoad();
				agv.setNextRoad(0);
				iAgv.saveCache(agv);
				iAgvEvent.toRoad(agv, p);
			}else {
				if (dot.getRouteRoad() > 0) { 
					iAgvEvent.toRoad(agv, dot.getRouteRoad());
				} else {
					MsgCore.sendMsg(agv.getAgvId(), "点位数据不全");
				}
			} 
		}
	}

	/**
	 * 传输位
	 */
	@Override
	public void arrivedTrans(AgvBean agv, DotBean dot) {
		// 记录点位信息
		iDot.setDotOfAgv(dot.getDotno(), agv.getAgvId());
		

		// 重置机台的传输状态（注意，到达传输工位，可能不是机台）
		StationBean station = iStation.getBeanByDot(dot.getDotno());
		if (station != null) {
			// 清理机台传输状态
			StationCmdMap.clearState(station.getDotno());

			//解锁充电桩
			iPower.unlockPowerByAgv(agv.getAgvId());
			
			// 锁定机台 并解锁其它点位
			iStation.lockStationOnTarget(dot.getDotno(), agv.getAgvId() ); 
			 
			 agv.setSpecialline(station.getSpecialline());
		 
			 if(station.isUpTrans()==false) {
				 agv.setUpHasTrans(true);
			 }
		  	if(station.isDownTrans()==false) {
			 	// 下层不可传=下层已经传输完成
				agv.setDownHasTrans(true); 
		  	}
			agv.setNextRoad(0); 
			agv.setToHC(false);
			agv.setFromHC(false);
			agv.setFinishTrans(false); 
			agv.setBothTrans(false);
			agv.setFakeLeave(false);
			agv.setNotClear(false);
		    agv.setCurrentTrans(AgvCurrentTransEnum.None); 
			iAgv.saveCache(agv);
		}

	}

	@Override
	public void arrivedWait(AgvBean agv, DotBean dot) {
		//  没有待命点

	}

	/**
	 * 能进此方法肯定是传输完成 AGV的目标路线由对接机台点位设置
	 */
	@Override
	public void arrivedQR(AgvBean agv, DotBean dot) {

		// 传输工位点位解锁
		int transdot = iDot.getTransDotNo(dot.getDotno());
		if (transdot > 0) {
			iDot.setDotOfAgv(transdot, 0);
			// 机台解锁 。只能解自己锁定的机台
			iStation.unlockStationForDot(transdot, agv.getAgvId());
		} 
	 
	    agv.setTransing(false); 
		agv.setFinishTrans(false);
		agv.setUpHasTrans(false);
		agv.setDownHasTrans(false); 
		iAgv.saveCache(agv);
 
		 //充电桩的不会进来
		 
		if( dot.getDotno()>250 &&dot.getDotno()<300 
				&& dot.getDotno()!=275 && dot.getDotno()!=277 
				&& dot.getDotno()!=253 && dot.getDotno()!=255 ) {
			//从二维码开始的路线
			if(agv.getNextRoad()>0 ) {
				iAgvEvent.toRoad(agv,agv.getNextRoad());
			}else {
				if (dot.getRouteRoad() > 0) {
					// 小车跑路 
					iAgvEvent.toRoad(agv, dot.getRouteRoad());
				} else {
					MsgCore.sendMsg(agv.getAgvId(), "数据错误，缺少目标路线"); 
				}
			}
		}else {
			if (dot.getRouteRoad() > 0) {
				// 小车跑路 
				iAgvEvent.toRoad(agv, dot.getRouteRoad());
			} else {
				MsgCore.sendMsg(agv.getAgvId(), "数据错误，缺少目标路线"); 
			}
		}
		

	}

	/**
	 * 到达普通点位
	 */
	@Override
	public void arrivedNormal(AgvBean agv, DotBean dot) {
		
		//logger.error( "点位"+dot.getDotno()+" 是普通点位， 没有事件.对应AgV="+agv.getAgvId());
	}

	/**
	 * 电量判断位
	 */
	@Override
	public void arrivedPowerCheck(AgvBean agv, AgvDataBean data, DotBean dot) {
		if(dot.getDotno()==364) {
			p364(agv,dot);
		}else if(dot.getDotno()==393) {
			p393(agv,data);
		}else if(dot.getDotno()==452) {
			p452(agv,data);
		} else if(dot.getDotno()==363) {
			p363(agv);
		}

	}

	@Override
	public void arrivedQRWithNoTrans(AgvBean agv, DotBean dot, AgvMountBean agvmount, int transDotno) {
		if (agvmount.getMountType() == AgvMountTypeEnum.Error) {
			// 错误的装卸情况，比如上X下空，上满下X，不处理
			MsgCore.sendMsg(agv.getAgvId(), "花篮数量异常，暂停");
			return;
		}
		//再次重置
		 agv.setTransing(false); 
		agv.setFinishTrans(false);
		agv.setUpHasTrans(false);
		agv.setDownHasTrans(false); 
		iAgv.saveCache(agv);
 
 
		// 二维码的点位处理
		if(transDotno>301&&transDotno<350) {
			//处理充电桩,只做释放
			iPower.unlockPowerNotice(transDotno);
			if(dot.getRouteRoad()>0) {
				iAgvEvent.toRoad(agv, dot.getRouteRoad());
			}else {
				MsgCore.sendMsg(agv.getAgvId(),dot.getDotno()+ "缺少路线");
			}
		}else if(transDotno>250 && transDotno<300) {
			//缓存机，非空不准走
			if (agvmount.getMountType() != AgvMountTypeEnum.AllEmpty) {
				// 错误的装卸情况，比如上X下空，上满下X，不处理
				MsgCore.sendMsg(agv.getAgvId(), "非空车不准移动");
				return;
			}
			if(dot.getRouteRoad()>0) {
				iAgvEvent.toRoad(agv, dot.getRouteRoad());
			}else {
				MsgCore.sendMsg(agv.getAgvId(),dot.getDotno()+ "缺少路线");
			} 
		}else {
			qrCheck.check(agv, dot , agvmount,transDotno) ;  
		}
		
	}

 

	// ********** 决策位判断方法 注意，大部分看着很像感觉能抽象，其实有细微差别。代码求稳！ *****************

	
	/**
	 * 只做点与点的路由，不做agv修改
	 * @param agv
	 * @param startDotno
	 * @param routeDotno
	 */
	void toDot(AgvBean agv, int startDotno ,int routeDotno) {
		int road = iRoad.getNormalRoad(startDotno, routeDotno);
		if (road > 0) {
			iAgvEvent.toRoad(agv, road); 
		} else {
			// 没有路线，数据上的错误 -1
			MsgCore.sendMsg(agv.getAgvId(), String.format("程序异常，请检查%d到%d有没有路线",  startDotno, routeDotno));
		}
	}
	 
	/**
	 * 找无线别的机台
	 * @param startDot
	 * @param agv
	 * @param process
	 * @param wait
	 */
	boolean findStationWithNoSpecial(DotBean startDot ,AgvBean agv,String process,boolean wait,TransDirectionEnum transType) {
		// 已经存在的
		StationGroupDao gbean =null;
		if(transType==TransDirectionEnum.OnlyOut) {
			gbean=iStation.fetchNextOutStation(startDot.getDotno(), agv.getAgvId(), process,  true);
		}else {
			gbean=iStation.fetchNextInStation(startDot.getDotno(), agv.getAgvId(), process, 0, true);
		}
		if (gbean == null) {
			//没找到
			if(wait) {
				// 没有机台，需要等下一个周期 
				return false;
			}else {
				//走路由
				if(startDot.getRouteRoad()>0) {
					agv.setNextRoad(0); 
					agv.setNextProcess("去下一道工序");
					agv.setNexttStationName(""); 
					iAgv.saveCache(agv);
					iAgvEvent.toRoad(agv, startDot.getRouteRoad());
					return true;
				}else { 
					return false;
				}
			} 
		} else {
			//有机台
			RoadDao roadDao = iRoad.getTransRoad(startDot.getDotno(), gbean.getDotno());
			if (roadDao != null && roadDao.getId() > 0) {
				decideAgvToRoad(agv, process, roadDao.getId(), gbean.getStationname(), gbean.getDotno()); 
			} else {
				// 没有路线，数据上的错误 -1
				MsgCore.sendMsg(agv.getAgvId(), String.format("程序异常，请检查%d到%d有没有路线", startDot.getDotno(), gbean.getDotno()));
			}
			return true;
		}
	}
	  
	
	boolean findBSGStation(DotBean startDot ,AgvBean agv) {
		// 已经存在的
	 
			StationGroupDao  gbean=iStation.fetchNextBSGOutStation(startDot.getDotno(), agv.getAgvId(), "BSG",7);
		 
		if (gbean == null) {
			//没找到
			return false;
		} else {
			//有机台
			RoadDao roadDao = iRoad.getTransRoad(startDot.getDotno(), gbean.getDotno());
			if (roadDao != null && roadDao.getId() > 0) {
				decideAgvToRoad(agv, "BSG", roadDao.getId(), gbean.getStationname(), gbean.getDotno()); 
			} else {
				// 没有路线，数据上的错误 -1
				MsgCore.sendMsg(agv.getAgvId(), String.format("程序异常，请检查%d到%d有没有路线", startDot.getDotno(), gbean.getDotno()));
			}
			return true;
		}
	}
	
	boolean findStationWithNoSpecial(DotBean startDot ,AgvBean agv,List<String> processlist,boolean wait,TransDirectionEnum transType) {
		// 已经存在的
		StationGroupDao gbean=null;
		// 上料的选择 (注意，有线别）
		if(transType==TransDirectionEnum.OnlyOut) {
			gbean=iStation.fetchNextOutStation(startDot.getDotno(), agv.getAgvId(), processlist,  true);
		}else {
			gbean=iStation.fetchNextInStation(startDot.getDotno(), agv.getAgvId(), processlist.get(0), 0, true);
		}
		if (gbean == null) {
			//没找到
			if(wait) {
				return false;
			}else {
				//走路由
				if(startDot.getRouteRoad()>0) {
					agv.setNextRoad(0); 
					agv.setNextProcess("去下一道工序");
					agv.setNexttStationName(""); 
					iAgv.saveCache(agv);
					iAgvEvent.toRoad(agv, startDot.getRouteRoad());
					return true;
				}else { 
					return false;
				}
			} 
		} else {
			//有机台
			RoadDao roadDao = iRoad.getTransRoad(startDot.getDotno(), gbean.getDotno());
			if (roadDao != null && roadDao.getId() > 0) {
				decideAgvToRoad(agv, gbean.getProcess(), roadDao.getId(), gbean.getStationname(), gbean.getDotno());
				
			} else {
				// 没有路线，数据上的错误 -1
				MsgCore.sendMsg(agv.getAgvId(), String.format("程序异常，请检查%d到%d有没有路线", startDot.getDotno(), gbean.getDotno()));
				 
			}
			return true;
		}
	}
	  
	
	/**
	 * 找有线别的机台(agv有料的情况）
	 * @param startDot
	 * @param agv
	 * @param process
	 * @param specialline
	 * @param wait
	 */
	boolean findStation (DotBean startDot ,AgvBean agv,String process, int specialline ,TransDirectionEnum transType ) {
		// 已经存在的
		StationGroupDao gbean=null;
		// 上料的选择 (注意，有线别）
		if(transType==TransDirectionEnum.OnlyOut) {
			gbean=iStation.fetchNextOutStation(startDot.getDotno(), agv.getAgvId(), process,  true);
		}else {
			gbean=iStation.fetchNextInStation(startDot.getDotno(), agv.getAgvId(), process, specialline , true);
		}

	   if (gbean == null) { 
			 // 没有机台，需要等下一个周期 
			 return false;
		} else {
			RoadDao roadDao = iRoad.getTransRoad(startDot.getDotno(), gbean.getDotno());
			if (roadDao != null && roadDao.getId() > 0) {
				decideAgvToRoad(agv, process, roadDao.getId(), gbean.getStationname(), gbean.getDotno()); 
				return true;
			} else {
				// 没有路线，数据上的错误 -1
				MsgCore.sendMsg(agv.getAgvId(), String.format("程序异常，请检查%d到%d有没有路线", startDot.getDotno(), gbean.getDotno()));
				return false;
			}
		}
	}
	 
	
	/**
	 * 去确定的目标机台
	 * @param agv
	 * @param process
	 * @param road
	 * @param stationname
	 * @param targetdotno
	 */
	void decideAgvToRoad(AgvBean agv, String process, int road, String stationname, int targetdotno) {
 
		// 重置机台传输数据
		StationCmdMap.clearState(targetdotno);
		if(stationname!=null&&stationname.equals("")==false) {
			MsgCore.sendMsg(agv.getAgvId(), "目标机台:" + stationname);
		}else {
			MsgCore.sendMsg(agv.getAgvId(), "寻找下一道工序" );
		}
		

		agv.setNextRoad(0); 
		agv.setNextProcess(process);
		agv.setNexttStationName(stationname);
		agv.setFinishTrans(false);
		agv.setUpHasTrans(false);
		agv.setDownHasTrans(false); 
		iAgv.saveCache(agv);
		
		iAgvEvent.toRoad(agv, road);
	}
	
	 

	/**
	 * 制绒上料决策点.如果是空车，就去364 
	 * @param agv
	 * @param data
	 * @return
	 */
	void d350(AgvBean agv, AgvDataBean data, DotBean dot) {
		if(agv.getAgvId()==19||agv.getAgvId()==20) {
			//发料车,直接去363 ，走111
			iAgvEvent.toRoad(agv, 111);   //直走，不调用toDot 
		}else { 
			//普通车
			if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
				// 全空车 
				boolean flag=iStation.findCache(CacheStationEnumType.ZRS,agv.getAgvId(),false, true);
				if (flag) {
					toDot(agv,dot.getDotno(),CacheStationEnumType.ZRS.getDotno()-1);
				} else {
					MsgCore.sendMsg(agv.getAgvId(), "准备去制绒下料");
					toDot(agv,dot.getDotno(),364);
				} 
			}else if(data.getMountType() == AgvMountTypeEnum.UpFullAndDownEmpty) {
				boolean flag=findStationWithNoSpecial(dot, agv, "制绒上料", false,TransDirectionEnum.OnlyIn);
				if(flag==false) {
					//找缓存机
					boolean tocache = iStation.findCache(CacheStationEnumType.ZRS,agv.getAgvId(),true, true);
					if (tocache) {
						toDot(agv,dot.getDotno(),CacheStationEnumType.ZRS.getDotno()-1);
					} else {
						MsgCore.sendMsg(agv.getAgvId(),  "制绒上料没有可用的机台，等待中");
					}
				} 
			}else {
				MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息，无法与制绒上料对接");
			} 
		} 
		
	}

	/**
	 * 判断制绒下料。如果没位子，去368
	 * 
	 * @param agv
	 * @param data
	 * @return
	 */
	void d366(AgvBean agv, AgvDataBean data, DotBean dot) {
		if (data.getMountType() != AgvMountTypeEnum.AllEmpty) {
			// 不是空车，报错
			MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息，只允许空车在此处");
			return;
		}
		
		/*
		if(agv.getNextProcess()!=null&&agv.getNextProcess().equals("碱抛下料")) {
			//后段的车
			toDot(agv, 366, 368); 
			return;
		}
		
		 //制绒没有的情况下，先考虑扩散下料(366-406)。扩散下料也没有的情况下，POAID
		//如果POPAID不可用，找碱抛。如果碱抛没有可用的（没有可用，不用锁），去BSG 
		boolean go = findStationWithNoSpecial(dot, agv, "制绒下料", true, TransDirectionEnum.OnlyOut);
		if (go == false) {
			//制绒下料没可用机台，去406，找扩散出料
			//toDot(agv, 366, 406); 
			//toDot(agv, 366, 368); 
		}else {
			//制绒下料可用 do nothing
		}
		*/
		if(agv.getNextProcess()!=null&&agv.getNextProcess().equals("碱抛下料")) {
			//碱抛的空车直接去368
			toDot(agv, 366, 368); 
			return;
		}
		 
	 boolean flag=	  findStationWithNoSpecial(dot, agv, "制绒下料", true, TransDirectionEnum.OnlyOut);
		 if(flag==false) {
			 MsgCore.sendMsg(agv.getAgvId(), "制绒下料没有可用的机台");
		 }
	}

	/**
	 * 只判断POPAID上料
	 * 
	 * @param agv
	 * @param data
	 * @return
	 */
	void d368(AgvBean agv, AgvDataBean data, DotBean dot) {
		 
		if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
			boolean flag = findStationWithNoSpecial(dot, agv, "POPAID下料", false, TransDirectionEnum.OnlyOut);
			if (flag == false) {
				//没有可用机台，空车去479
				toDot(agv,dot.getDotno(),479);
			}
			return;
		}
		if (data.getMountType() != AgvMountTypeEnum.UpEmptyAndDownFull) {
			// 不是上空下满
			MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息，无法给POPAID上料");
			return;
		}  
		//碱抛下料离开机台时已经确定的popaid上料机台和缓存机。此处找不到机台只能等
		findStation(dot, agv, "POPAID上料", agv.getSpecialline() , TransDirectionEnum.OnlyIn);
		  
	}

	/**
	 * 去406,或者制绒下料缓存机
	 * 
	 * @param agv
	 * @param data
	 * @return
	 */
	void d478(AgvBean agv, AgvDataBean data, DotBean dot) {
		 //制绒下料到扩散上料，去406点
		toDot(agv,dot.getDotno(),406);
		
	}

	/**
	 * 有料的车到这里前已经锁定了机台了，直接去机台。空车直接去下个站
	 * 
	 * @param agv
	 * @param data
	 * @param dotno
	 * @return
	 */
	void d425(AgvBean agv, AgvDataBean data, DotBean dot) {
		if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
			
			//碱抛下料不享受充电桩
			if(agv.getNextProcess()!=null&&agv.getNextProcess().equals("碱抛下料")) {
				toDot(agv,dot.getDotno(),450);
				return;
			}
			
			 //充电桩选择
			if(data.getPower()<60) {
				//充电
				if(iPower.agvToPower(425, agv)) {
					return;
				}
			}
			 
			//空车考虑的是出料,特例方法
			boolean flag=findBSGStation(dot, agv);
			if(flag==false) {
				//没有机台可用，去450
				agv.setNextProcess("制绒下料");
				iAgv.saveCache(agv);
				toDot(agv,dot.getDotno(),450);
			} 
			return;
		}
		if (data.getMountType() != AgvMountTypeEnum.UpEmptyAndDownFull) {
			MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息，请检查AGV是否人为移动");
			return;
		}
		//上空下满，给BSG上料
		boolean flag=findStation(dot, agv, "BSG", agv.getSpecialline() , TransDirectionEnum.OnlyIn);	
		if(flag==false) {
			MsgCore.sendMsg(agv.getAgvId(), "没有可用的BSG机台");
		}
	}
 

	/**
	 * 判断扩散 
	 * 
	 * @param agv
	 * @param data
	 * @param dotno
	 */
	void d406(AgvBean agv, AgvDataBean data, DotBean dot) { 
		if(data.getMountType()==AgvMountTypeEnum.AllEmpty ) { 
			//退火下料的返空车，直接去366点，不参与此处的调度
			if(agv.getNextProcess()!=null&&agv.getNextProcess().equals("碱抛下料")) {
				// 去366点
				iAgvEvent.toRoad(agv, 168);
				return;
			}
			//空车，接扩散下料，没有就去bsg
			//1。找制绒下料缓存(出料模式
			boolean hasCache=iStation.findCache(CacheStationEnumType.ZRX, agv.getAgvId(), false, true);
			if(hasCache) {
				toDot(agv, 406, CacheStationEnumType.ZRX.getDotno()-1);
				return;
			}
			//2。找扩散下料（出料模式）
			hasCache = iStation.findCache(CacheStationEnumType.KS, agv.getAgvId(), false, true);
			if (hasCache) {
				toDot(agv, 406, CacheStationEnumType.KS.getDotno()-1);
				return;
			}
			 
			boolean flag=findStationWithNoSpecial(dot, agv,  "扩散下料" , false, TransDirectionEnum.OnlyOut); 
			if(flag==false) { 
				//正式的去425
				 toDot(agv, 406, 425); 
				
				//测试： 去366等
				//iAgvEvent.toRoad(agv, 168);
			} 
			return; 
		}else if(data.getMountType()==AgvMountTypeEnum.UpEmptyAndDownFull) {
			//上空下满，不一定是扩散上料，一些异常存在，可能是碱抛下料。这里的判断不能省
			if(agv.getNextProcess()!=null&&(agv.getNextProcess().equals("扩散上料")||agv.getNextProcess().equals("制绒下料"))  ) { 
				boolean flag=findStation(dot, agv, "扩散上料", agv.getSpecialline(), TransDirectionEnum.OnlyIn ); 
				if(flag==false) {
					//没有可用机台，找缓存机
					flag = iStation.findCache(CacheStationEnumType.ZRX, agv.getAgvId(), true, true);
					if(flag==false) {
						//没有缓存机用
						MsgCore.sendMsg(agv.getAgvId(), "目标工序：扩散上料。暂无可用机台和缓存" );
					}else {
						//去缓存机
						toDot(agv, dot.getDotno(), CacheStationEnumType.ZRX.getDotno()-1);
					}
				}
			}else { 
				//非扩散的工序，比发碱抛，去368,走159路 
				iAgvEvent.toRoad(agv, 159);
			} 
		}else {
			MsgCore.sendMsg(agv.getAgvId(), "请检查AGV的来源，装料信息不对AGV无法去下道工序："+agv.getNextProcess());
		}
	 }

	/**
	 * 如果碱抛没有可用机台 
	 * @param agv
	 * @param data
	 * @param dotno
	 */
	void d437(AgvBean agv, AgvDataBean data, DotBean dot) {
		if(data.getMountType()==AgvMountTypeEnum.AllEmpty) {
			if(agv.getNextProcess()!=null &&agv .getNextProcess().equals("BOE下料")) {
				//直接去392 
				toDot(agv, dot.getDotno(), 392); 
				return; 
			}
			/*
			if(agv.getNextProcess()!=null&&agv.getNextProcess().equals("退火下料")) {
				//直接去479
				toDot(agv, dot.getDotno(), 479); 
				return; 
			}
			 */
			
			//不是BOE下料的车，电量充足，全部参与碱抛下料的操作
			//没有机台就去366
			
			//空车
			/*
			if(data.getPower()<60) {
				//电量不足，直接去350
				toDot(agv, dot.getDotno(), 350);
				return;
			}
			*/
			
			if(agv.getNextProcess()!=null&&agv.getNextProcess().equals("制绒下料")) {
				//直接去350
				toDot(agv, dot.getDotno(), 350); 
				return; 
			}
			
			agv.setNextProcess("碱抛下料");
			iAgv.saveCache(agv);
			String process="碱抛下料";
			boolean flag=findStationWithNoSpecial(dot, agv, process, false, TransDirectionEnum.OnlyOut);
			if(flag==false) { 
				//没有碱抛下料机台，去缓存机
				flag=iStation.findCache(CacheStationEnumType.TH, agv.getAgvId(), false, true);
				if(flag ) { 
					//去缓存
					toDot(agv, dot.getDotno(), CacheStationEnumType.TH.getDotno()-1);
					return;
				} 
				flag=iStation.findCache(CacheStationEnumType.BSG, agv.getAgvId(), false, true);
				if(flag ) { 
					//去缓存
					toDot(agv, dot.getDotno(), CacheStationEnumType.BSG.getDotno()-1);
					return;
				} 
				flag=iStation.findCache(CacheStationEnumType.JP, agv.getAgvId(), false, true);
				if(flag ) { 
					//去缓存
					toDot(agv, dot.getDotno(), CacheStationEnumType.JP.getDotno()-1);
					return;
				} 
				
				//没有缓存机台用，去366
				toDot(agv, dot.getDotno(), 366); 
				return; 
			} 
			return; 
		}else if(data.getMountType()==AgvMountTypeEnum.UpFullAndDownEmpty) { 
			//上满下空，BSG来的空花篮 去350
		    toDot(agv, dot.getDotno(), 350); 
		}else{
			MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。AGV下道工序：" + agv.getNextProcess());
		} 
	}

	/**
	 * 退火工序判断点，要么上料，要么接料
	 * 或者去充电（低于70%）
	 * @param agv
	 * @param data
	 * @param dotno
	 */
	void d479(AgvBean agv, AgvDataBean data, DotBean dot) {  
		if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
			if(data.getPower()<70) {
				//去充电
				if(iPower.agvToPower(479, agv)) {
					return;
				}
			} 
			String process="退火下料";
			boolean flag=findStationWithNoSpecial(dot, agv, process, false, TransDirectionEnum.OnlyOut);
			if(flag==false) {
				//空车去390
				//iAgvEvent.toRoad(agv, 161);
				agv.setNextProcess("BOE下料");
				iAgv.saveCache(agv);
				toDot(agv, 479, 392);
				return; 
			}
		}else if(data.getMountType()==AgvMountTypeEnum.UpEmptyAndDownFull) {
			String process="退火上料";
			if(agv.isFromHC()) {
				//来自缓存机
				boolean f=	findStation(dot, agv, process, agv.getSpecialline() , TransDirectionEnum.OnlyIn);
				if(f==false) {
					//原地不动
				} 
			}else {
				//从popaid出来的
				boolean flag=findStation(dot, agv, process, agv.getSpecialline() , TransDirectionEnum.OnlyIn);
				if(flag==false) {
					//找缓存机
					flag=iStation.findCache(CacheStationEnumType.POPAID, agv.getAgvId(), true, true);
					if(flag==false) {
						//popaid1也没有找到 ,等
						 
					}else {
						//去POPAID1
						toDot(agv, dot.getDotno(), CacheStationEnumType.POPAID.getDotno()-1);
					}
					
				}
			}
			
			 
			
		}else {
			MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。AGV下道工序：" + agv.getNextProcess());
		} 
	}
	
	
	void d403(AgvBean agv, AgvDataBean data, DotBean dot) {  
		if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
			agv.setNextProcess("退火下料");
			iAgv.saveCache(agv);
			 toDot(agv, 403, 366); 
		}else {
			if(iStation.stationCanUse(74, agv.getAgvId())) { 
				iAgvEvent.toRoad(agv, 105);
			}else {
				/*
				if(iStation.stationCanUse(76, agv.getAgvId())) {
					iAgvEvent.toRoad(agv, 106);
				}else {
					MsgCore.sendMsg(agv.getAgvId(), "非空车不能移动");
				} 
				*/
				//2号机台只要开启
				if(iStation.stationNotDisable(76)) {
					//走411拐进去
					iAgvEvent.toRoad(agv, 411);
				}else {
					MsgCore.sendMsg(agv.getAgvId(), "非空车不能移动");
				}
			} 
		} 
	}


	/**
	 * 如果是空车，则去BOE下料，或者451
	 * 。如果是退火出来的，去BOE上料
	 * 
	 * @param agv
	 * @param data
	 * @param dotno
	 */
	void d390(AgvBean agv, AgvDataBean data, DotBean dot) { 
		if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
			if(data.getPower()<70) {
				//充电
				if(iPower.agvToPower(392, agv)) {
					return;
				}
			}
			
			String process= "BOE下料";
			boolean flag=findStationWithNoSpecial(dot, agv, process, false, TransDirectionEnum.OnlyOut);
			if(flag==false) {
				//去392
				toDot(agv, 390, 392); 
				return; 
			} 
			
			//应该去空车直接去437
		}else if(data.getMountType()==AgvMountTypeEnum.UpEmptyAndDownFull) {
			if(agv.getNextProcess()!=null&&agv.getNextProcess().equals("BOE上料")) {
				String process="BOE上料";
				findStation(dot, agv, process, agv.getSpecialline() , TransDirectionEnum.OnlyIn );
			}else {
				MsgCore.sendMsg(agv.getAgvId(), "AGV不应该出现在此处，当前工序：" + agv.getNextProcess()); 
			}
		}else {
			MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。AGV下道工序：" + agv.getNextProcess());
		}  
	}
	
	
	/**
	 * 与390相似，不考虑缓存机
	 * @param agv
	 * @param data
	 * @param dot
	 */
	void d392(AgvBean agv, AgvDataBean data, DotBean dot) { 
		DotBean dot390=iDot.getBean(390);  //按390的点来做计算
		if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
			if(data.getPower()<70) {
				//充电
				if(iPower.agvToPower(390, agv)) {
	 				return;
	 			}
			}
			// 
			if(agv.getNextProcess()!=null &&agv .getNextProcess().equals("BOE下料")) {
				String  process= "BOE下料";
				//从390开始查 
				boolean flag=findStationWithNoSpecial(dot390, agv, process, false, TransDirectionEnum.OnlyOut);
				if(flag==false) {
					//去451 ，拿ALD的花篮
					toDot(agv, dot390.getDotno(), 451);
				} 
			}else {
				//BOE下料不可用，去退火下料 
				if(iStation.hasEmpty("退火下料")) {
					agv.setNextProcess("退火下料");
					iAgv.saveCache(agv);
					iAgvEvent.toRoad(agv, 155); 
				}else {
					/*
					String  process= "BOE下料";
					//从390开始查 
					boolean flag=findStationWithNoSpecial(dot390, agv, process, false, TransDirectionEnum.OnlyOut);
					if(flag==false) {
						//去451 ，拿ALD的花篮
						toDot(agv, dot390.getDotno(), 451);
					} 
					*/
				  
					//直接去397 
					agv.setNextProcess("");
					iAgv.saveCache(agv);
					iAgvEvent.toRoad(agv, 155);  
				}
				return;
			} 
		}else if(data.getMountType()==AgvMountTypeEnum.UpEmptyAndDownFull) {
			if(agv.getNextProcess()!=null ) { 
				String process="BOE上料";
				boolean flag;
				if(agv.isFromHC())
				{
					//缓存机出来的
					flag=findStation(dot390, agv, process, agv.getSpecialline() , TransDirectionEnum.OnlyIn );
					if(flag==false) {
						//没找到，等
					}
				}else {
					//从退火下料出来的
					flag=findStation(dot390, agv, process, agv.getSpecialline() , TransDirectionEnum.OnlyIn );
					if(flag==false) {
						flag=iStation.findCache(CacheStationEnumType.TH, agv.getAgvId(), true, true);
						if(flag==false) {
							//缓存机不可用，等
						}else {
							toDot(agv, dot.getDotno(), CacheStationEnumType.TH.getDotno());
						}
					} 
				} 
			}else {
				MsgCore.sendMsg(agv.getAgvId(), "AGV不应该出现在此处，当前工序：" + agv.getNextProcess());
			}
		
		}else {
			MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。AGV下道工序：" + agv.getNextProcess());
		}  
	}

	/**
	 * 碱抛上空花篮判断点。如果是空车，去437
	 * 
	 * @param agv
	 * @param data
	 * @param dotno
	 */
	void d397(AgvBean agv, AgvDataBean data, DotBean dot) { 
		if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
			// 空车去437 ，让437做决策
			agv.setNextProcess("退火下料");
			iAgv.saveCache(agv);
			toDot(agv, dot.getDotno(), 437);  
		} else if(data.getMountType() == AgvMountTypeEnum.UpFullAndDownEmpty) {
			String process = "碱抛上料";
			 
			// 碱抛上料是空花篮，不需要线别
			boolean flag = findStationWithNoSpecial(dot, agv, process, true, TransDirectionEnum.OnlyIn);
			if (flag == false) {
				//机台不可用，找缓存机。缓存机不可用，走327
				boolean tocache = iStation.findCache(CacheStationEnumType.BSG,agv.getAgvId(), true,true);
				if (tocache) {
					// 可以去缓存 
					toDot(agv, dot.getDotno(), CacheStationEnumType.BSG.getDotno());
				} else {
					// 直接走105去碱抛上料
					agv.setNextRoad(0);
					agv.setNextProcess("去下一道工序");
					agv.setNexttStationName("");
					iAgv.saveCache(agv);
					MsgCore.sendMsg(agv.getAgvId(), "需要卸载来自ALD的空花篮");
					iAgvEvent.toRoad(agv, 327); 
				}
			}
		}else {
			MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。AGV下道工序：" + agv.getNextProcess());
			
		} 
	}
	
	
	 

	/**
	 * ALD湿法上料判断点，空车就去452
	 * 
	 * @param agv
	 * @param data
	 * @param dotno
	 */
	void d451(AgvBean agv, AgvDataBean data, DotBean dot) { 
		if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
			// 空车 
			if(agv.getPower()<50) {
				MsgCore.sendMsg(agv.getAgvId(), "去充电");
				toDot(agv, dot.getDotno(), 393);
				return;
			}  
			//List<String> processList=Arrays.asList("ALD湿法","ALD干法","丝网");
			//去干法拿料
			List<String> processList=Arrays.asList("ALD干法");
			boolean flag=findStationWithNoSpecial (dot,agv,processList,false, TransDirectionEnum.OnlyOut);
			if(flag==false) {
				//空车，找不到就去充电
				// 入缓存机的判断 BMX,SW
				flag = iStation.findCache(CacheStationEnumType.BMX1, agv.getAgvId(), false, true);
				if (flag) {
					// 去缓存
					toDot(agv, dot.getDotno(), CacheStationEnumType.BMX1.getDotno() - 1);
					return;
				}
				flag = iStation.findCache(CacheStationEnumType.BMX2, agv.getAgvId(), false, true);
				if (flag) {
					// 去缓存
					toDot(agv, dot.getDotno(), CacheStationEnumType.BMX2.getDotno() - 1);
					return;
				}
				flag = iStation.findCache(CacheStationEnumType.SW, agv.getAgvId(), false, true);
				if (flag) {
					// 去缓存
					toDot(agv, dot.getDotno(), CacheStationEnumType.SW.getDotno() - 1);
					return;
				}

				// 没有缓存机台可用的空车，去393
				toDot(agv, dot.getDotno(), 393);
			} 
		}else if(data.getMountType() == AgvMountTypeEnum.UpEmptyAndDownFull) {
			if(agv.isFromHC() && agv.getNextProcess()!=null&&agv.getNextProcess().equals("丝网")) {
				//来自背膜下料的缓存机
				String process="丝网";
				boolean flag =findStation(dot, agv, process, agv.getSpecialline(), TransDirectionEnum.OnlyIn );
				if(flag==false) {
					//没机台，AGV不动
				}
			}else if(agv.isFromHC() &&agv.getNextProcess()!=null&&agv.getNextProcess().equals("ALD湿法")){
				//来自BOE下料的缓存
				String process="ALD湿法";
				boolean flag =findStation(dot, agv, process, agv.getSpecialline(), TransDirectionEnum.OnlyIn );
				if(flag==false) {
					//没机台，AGV不动
				}
			}else if(agv.isFromHC() &&agv.getNextProcess()!=null&&agv.getNextProcess().equals("ALD干法")){
				//来自BOE下料的缓存
				String process="ALD干法";
				boolean flag =findStation(dot, agv, process, agv.getSpecialline(), TransDirectionEnum.OnlyIn );
				if(flag==false) {
					//没机台，AGV不动
				}
			}else {
				String process="ALD湿法";
				boolean flag=	findStation(dot, agv, process, agv.getSpecialline(), TransDirectionEnum.OnlyIn );
				if(flag==false) {
					//找BOE缓存1
					flag=iStation.findCache(CacheStationEnumType.BOE1, agv.getAgvId(), true, true);
					if(flag==false) { 
						//去boe1缓存
						toDot(agv, dot.getDotno(), CacheStationEnumType.BOE1.getDotno()-1);
					}
				} 
			} 
		}else if(data.getMountType() ==AgvMountTypeEnum.UpFullAndDownEmpty) {
			if(agv.getNextProcess().equals("碱抛上料")) {
				//去397
				toDot(agv, 452, 397); 
			}else {
				MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息。当前工序：" + agv.getNextProcess()); 
			}
		}else {
			MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。当前工序：" + agv.getNextProcess()); 
		} 
	}
 

	/**
	 * 判断去缓存机还是去正膜上料。如果是空车，去正膜背膜下料拿料
	 * 
	 * @param agv
	 * @param data
	 * @param dotno
	 */
	void d475(AgvBean agv, AgvDataBean data, DotBean dot) { 
		 
		if (data.getMountType() == AgvMountTypeEnum.UpEmptyAndDownFull) {
			String	process = "正膜上料";
			findStation(dot, agv, process, agv.getSpecialline() , TransDirectionEnum.OnlyIn); 
		}else if(data.getMountType()==AgvMountTypeEnum.AllEmpty) {
			//1。先找 ALD下料缓存和 正膜上料是否可用
			/*
			String process="正膜上料"; 
			boolean flag=iStation.hasEmpty(process);
			if(flag) {
				//有正膜上料的机台可用
				flag=iStation.findCache(CacheStationEnumType.ZMS, agv.getAgvId(), false,true);
				if(flag) {
					//ald下料（正膜上料）的缓存机可用
					toDot(agv, dot.getDotno(), CacheStationEnumType.ZMS.getDotno());
					return;
				}
			}
			
			//2。背膜上料 + 正膜下料缓存机台用
			process="背膜上料"; 
			flag=iStation.hasEmpty(process);
			if(flag) {
				//有背膜上料的机台可用
				flag=iStation.findCache(CacheStationEnumType.ZMX, agv.getAgvId(), false,true);
				if(flag) {
					//正膜下料的缓存机可用
					toDot(agv, dot.getDotno(), CacheStationEnumType.ZMX.getDotno());
					return;
				}
			}
			 */
			
			//机台下料选择
			List<String> processList=Arrays.asList("正膜下料","背膜下料"); 
		  boolean   flag=findStationWithNoSpecial(dot, agv, processList, false, TransDirectionEnum.OnlyOut);
			if(flag==false) { 
				 
				 //没有可用的机台，等待
				//MsgCore.sendMsg(agv.getAgvId(), "没有可用的机台，等待");
				//去476
				int road=iRoad.getNormalRoad(475, 476);
				if(road>0) {
					iAgvEvent.toRoad(agv, road);
				}else {
					MsgCore.sendMsg(agv.getAgvId(), "没有可用的机台，等待");	
				}
			}
		}else {
			MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。AGV下道工序：" + agv.getNextProcess());
			
		} 
	}
	
	
	/**
	 * 处理 76 78两个点
	 * @param agv
	 * @param data
	 * @param dot
	 */
	void d729 (AgvBean agv, AgvDataBean data, DotBean dot) { 
		if(iStation.stationCanUse(76, agv.getAgvId())) {
			//76可用，走106
			iStation.lockStationOnTarget(76, agv.getAgvId());
			iAgvEvent.toRoad(agv, 106);
		}else if(iStation.stationCanUse(78, agv.getAgvId())) {
			//78可用，走107
			iStation.lockStationOnTarget(78, agv.getAgvId());
			iAgvEvent.toRoad(agv, 107);
		}else {
			MsgCore.sendMsg(agv.getAgvId(), "没有可用的机台，等待");
		}
		
	}
	
	
	/**
	 * 镀膜出来的点
	 * @param agv
	 * @param data
	 * @param dot
	 */
	void d476(AgvBean agv, AgvDataBean data, DotBean dot) { 
	   
		if (data.getMountType() == AgvMountTypeEnum.UpEmptyAndDownFull) { 
			//上空下满，必须定线查找
			findStation(dot, agv, "丝网", agv.getSpecialline() , TransDirectionEnum.OnlyIn); 
		}else if(data.getMountType()==AgvMountTypeEnum.AllEmpty) { 
			 
			
			String process = "ALD干法" ; 
			boolean flag=findStationWithNoSpecial(dot, agv, process, false, TransDirectionEnum.OnlyOut);
			if(flag==false) {
				//ALD干法没有可用的机台
				//1。如果丝网+背膜下料缓存可用
				flag=iStation.hasEmpty(process);
				if(flag) {
					//丝网有空位
					boolean c1=iStation.findCache(CacheStationEnumType.BMX1, agv.getAgvId(), false, true);
					if(c1) {
						//缓存机1出料可用
						toDot(agv, dot.getDotno(), CacheStationEnumType.BMX1.getDotno()-1);
						return;
					}else {
						c1=iStation.findCache(CacheStationEnumType.BMX2, agv.getAgvId(), false, true);
						if(c1) {
							//缓存机2出料可用
							toDot(agv, dot.getDotno(), CacheStationEnumType.BMX2.getDotno()-1);
							return;
						}
					}  
				}
				//2.ALD湿法有位子+BOE下料缓存可用
				process = "ALD湿法";
				flag = iStation.hasEmpty(process);
				if (flag) {
					// BOE1有空位
					boolean c1 = iStation.findCache(CacheStationEnumType.BOE1, agv.getAgvId(), false, true);
					if (c1) {
						// 缓存机1出料可用
						toDot(agv, dot.getDotno(), CacheStationEnumType.BOE1.getDotno() - 1);
						return; 
					} 
				}
				
				//3.popaid2号机（靠BOE）+退火上料
				process = "退火上料";
				flag = iStation.hasEmpty(process);
				if (flag) {
					// BOE1有空位
					boolean c1 = iStation.findCache(CacheStationEnumType.TH, agv.getAgvId(), false, true);
					if (c1) {
						// 退火出料可用
						toDot(agv, dot.getDotno(), CacheStationEnumType.TH.getDotno() - 1);
						return;
					} 
				}
				
				//去452
				toDot(agv, 476, 452);
			}else {
				//有机台可用，不处理
			}
			 
		}else {
			MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。当前工序：" + agv.getNextProcess());
			
		} 
	}
	
	
	/**
	 * 制绒下料充电
	 * @param agv
	 */
	void p364(AgvBean agv, DotBean dot) { 
		if(agv.getPower()<70) {
 			if(iPower.agvToPower(364, agv)) {
 				return;
 			}
		}
	 
		StationGroupDao	gbean=iStation.fetchNextOutStation(364, agv.getAgvId(), "制绒下料",  true);
		 if(gbean!=null) {
			 //去366
			 toDot(agv, 364, 366);
		 }else {
				MsgCore.sendMsg(agv.getAgvId(), "制绒下料无机台可用，等待");
		 }
		   
	
	}
	
	
	/**
	 * 发料小车专用充电
	 * @param agv
	 */
	void p363(AgvBean agv) { 
		if(agv.getAgvId()==19||agv.getAgvId()==20) {
			if(agv.getPower()<70) {
	 			if(iPower.agvToPower(363, agv)) {
	 				return;
	 			}
			} 
			toDot(agv, 363, 201); 
		}
		else {
			MsgCore.sendMsg(agv.getAgvId(), "非发料AGV不应该停在此处");
		}
	}
	
	
	/**分支点
	 * @param agv
	 * @param amount
	 */
	void p452(AgvBean agv,AgvDataBean amount) {  
		if(amount.getMountType()==AgvMountTypeEnum.AllEmpty) {
			//空车和上空下满去393
			if(amount.getPower()<70) {
				//去充电
				if(iPower.agvToPower(452, agv)) {
					return  ;
				}
				//452没位置了，去中间
				toDot(agv, 452, 393);  
			}else {
				//去397，那边安排 去退火
				//进入5台缓存机的判断
				boolean flag=iStation.findCache(CacheStationEnumType.BMX1, agv.getAgvId(), false, true);
				if(flag ) {
					toDot(agv, 452, CacheStationEnumType.BMX1.getDotno()-1); 
					return;
				} 
				flag=iStation.findCache(CacheStationEnumType.BMX2, agv.getAgvId(), false, true);
				if(flag ) {
					toDot(agv, 452, CacheStationEnumType.BMX2.getDotno()-1); 
					return;
				} 
				flag=iStation.findCache(CacheStationEnumType.SW, agv.getAgvId(), false, true);
				if(flag ) {
					toDot(agv, 452, CacheStationEnumType.SW.getDotno()-1); 
					return;
				} 
				flag=iStation.findCache(CacheStationEnumType.BOE1, agv.getAgvId(), false, true);
				if(flag ) {
					toDot(agv, 452, CacheStationEnumType.BOE1.getDotno()-1); 
					return;
				} 
				 
				//没有可用的缓存，去397
				toDot(agv, 452, 397);  
			}
		}else if(amount.getMountType()==AgvMountTypeEnum.UpEmptyAndDownFull) {
			toDot(agv, 452, 393);   
		}else if(amount.getMountType()==AgvMountTypeEnum.UpFullAndDownEmpty) {
			//上满下空
			if(agv.getNextProcess().equals("碱抛上料")) {
				toDot(agv, 452, 397);  
			}else {
				MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。当前工序：" + agv.getNextProcess()); 
			} 
		}else {
			MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。当前工序：" + agv.getNextProcess()); 
		} 
	}
	
	

	/**
	 * 镀膜充电
	 * @param agv
	 * @param amount
	 */
	void p393(AgvBean agv,AgvDataBean amount) { 
		if(amount.getMountType()==AgvMountTypeEnum.AllEmpty ) {
			if(agv.getPower()<80) {
				if(iPower.agvToPower(393, agv)) {
					 
				}else {
					MsgCore.sendMsg(agv.getAgvId(), "电量不足，AGV无法胜任工作"  );
				}
				return;
			} 
			boolean flag=iStation.hasEmpty(Arrays.asList("正膜下料","背膜下料"));
			if(flag==false) {
				//没有可用的下料机台，也去充电
				if(iPower.agvToPower(393, agv)) {
					return;
				}
			} 
			//去475，走137 
			toDot(agv, 393, 475);  
		}else 	if(amount.getMountType()==AgvMountTypeEnum.UpEmptyAndDownFull ) {
			//带料的也去475
			toDot(agv, 393, 475);  
		}else {
			MsgCore.sendMsg(agv.getAgvId(), "错误的装料信息,只能人工处理。AGV下道工序：" + agv.getNextProcess());
		} 
	}
	
	void d518(AgvBean agv, AgvDataBean data, DotBean dot) { 
		 if(data.getMountType()==AgvMountTypeEnum.AllEmpty) {
			//1。先找 ALD下料缓存和 正膜上料是否可用
			String  process="碱抛下料"; 
			boolean flag=findStationWithNoSpecial(dot, agv, process, false, TransDirectionEnum.OnlyOut);
			if(flag==false) {
				//去406，走256
				agv.setNextProcess("碱抛下料");
				iAgv.saveCache(agv);
				iAgvEvent.toRoad(agv, 256);
			} 
		}else {
			MsgCore.sendMsg(agv.getAgvId(), "只有空车能移动"  );
			
		} 
	}
	
	
	void d477(AgvBean agv, AgvDataBean data, DotBean dot) { 
		if (data.getMountType() == AgvMountTypeEnum.AllEmpty) {
			// 空车，走164，去452
			iAgvEvent.toRoad(agv, 164);
		} else if (data.getMountType() == AgvMountTypeEnum.UpEmptyAndDownFull) {
			if (agv.isFromHC()) {
				// 只能去ALD干法
				boolean flag = findStationWithNoSpecial(dot, agv, "ALD干法", true, TransDirectionEnum.OnlyIn);
				if (flag == false) {
					// 等
				}
			} else {
				MsgCore.sendMsg(agv.getAgvId(), "缓存机卸料专用点位，请人工处理");
			}
		} else {
			MsgCore.sendMsg(agv.getAgvId(), "只有空车能移动");

		}
	}
	
}
